home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MCASM.RAR / MC_ASM.EXE / WROX_ASM / CH13 / MEMVIEW.ASM < prev    next >
Assembly Source File  |  1994-11-15  |  10KB  |  545 lines

  1. ; This program prints out the list of MCBs
  2. ; (Memory Control Blocks) from the PC memory.
  3. ; When run with the switch /D, it prints out
  4. ; the list of drivers.
  5. ; Demo program for ExpAsm Chapter 13 Memory Management under 1Mb
  6. ; written by Yuri Kisselev. Autumn 1991 - Summer 1994 ^Z Minsk RB.
  7.  
  8. .286
  9. dosseg
  10. .model small
  11. .stack 100h
  12. .data
  13.     addr_str db 'Address'
  14.     sys_str db 'System'
  15.     name_str db 'Name'
  16.     type_str db 'Type'
  17.     size_str db 'Size'
  18.     dat  db 'Data'
  19.     cod  db 'Code'
  20.     env db 'Environment'
  21.     prg db 'Program'
  22.     msd db 'MSDOS'
  23.     fre db 'Free'
  24.     unkn db 'Unknown'
  25.     OldDOS db 'Incorrect DOS version .',13,10,'$'
  26.     hex db '0123456789ABCDEF'    ; Table for hex convertion
  27.     buff_str db 50 dup (0),13,10,'$'; String buffer
  28.     flag_link_UMB db 0
  29. .code
  30. Start:
  31.         mov ax,@data
  32.         mov ds,ax        ; Load data segment
  33.  
  34.         mov bx,ss
  35.         sub bx,ax
  36.         shl bx,4
  37.         cli
  38.         mov ss,ax        ; Load stack pointer
  39.         add sp,bx
  40.         sti
  41.         mov bx,sp        ; Calculate the size of program
  42.                     ; memory block
  43.         add bx,15        ; Round up to next paragraph
  44.         shr bx,4
  45.         add ax,bx
  46.         mov bx,es
  47.         sub ax,bx
  48.         mov bx,ax
  49.         mov ah,4ah
  50.         int 21h            ; Resize program memory block
  51.  
  52.         mov ah,30h
  53.         int 21h            ; Get DOS version
  54.         cmp al,5        ; Check DOS version (5.0)
  55.         jnb ok_dos
  56.         mov ah,9
  57.         lea dx,OldDOS
  58.         int 21h
  59.  
  60.         mov ah,4ch
  61.         int 21h            ; terminate program
  62. ok_dos:
  63.         mov ax,5802h
  64.         int 21h            ; Get Upper Memory link
  65.         mov flag_link_UMB,al    ; Save it
  66.  
  67.         mov ax,5803h
  68.         mov bx,1
  69.         int 21h            ; Set upper memory link
  70.  
  71.         ; Look for /d in command line (show device drivers)
  72.  
  73.         mov di,81h
  74.         mov cl,es:[di-1]
  75.         mov al,'/'
  76.         repne scasb
  77.         jne show_mcb
  78.         cmp byte ptr es:[di],'D'
  79.         je show_drivers
  80.         cmp byte ptr es:[di],'d'
  81.         je show_drivers
  82. show_mcb:
  83.                 ; show the MCBs
  84.         call Display_MCB
  85.         jmp short exit_prg
  86. show_drivers:
  87.                 ; show the DRVs
  88.         call Display_DRV
  89. exit_prg:
  90.         mov ax,5803h
  91.         xor bx,bx
  92.         mov bl,flag_link_UMB
  93.         int 21h            ; Restore upper memory link
  94.  
  95.         mov ax,4c00h
  96.         int 21h            ; Exit program
  97.  
  98. ; show drivers chain
  99. Display_DRV    proc near
  100.         xor cx,cx        ; Fill header string
  101.         mov ax,ds
  102.         mov es,ax
  103.         mov di,offset buff_str
  104.         mov dx,di
  105.         inc di
  106.         mov si,offset addr_str
  107.         mov cl,7
  108.         rep movsb
  109.         add di,7
  110.         mov si,offset name_str
  111.         mov cl,4
  112.         rep movsb
  113.  
  114.         mov ah,9
  115.         int 21h            ; Print header
  116.  
  117.         mov di,offset buff_str
  118.         mov ax,2d2dh
  119.         mov cl,15
  120.         rep stosw        ; "-----------"
  121.  
  122.         mov ah,9
  123.         int 21h
  124.  
  125.         mov ah,52h
  126.         int 21h            ; Get DOS List Of Lists (ES:BX)
  127.         add bx,22h        ;  ES:BX -> NUL device
  128. next_drv:
  129.         mov dx,es
  130.         mov ax,ds
  131.         mov es,ax
  132.         mov di,offset buff_str
  133.         mov si,di
  134.         mov cx,25
  135.         mov ax,2020h
  136.         rep stosw        ; Fill string with spaces
  137.         mov es,dx
  138.  
  139.         push bx
  140.         push bx
  141.         xor bx,bx
  142.         mov ax,es
  143.         call PutHexWord        ; Put driver segment
  144.         mov byte ptr [si],':'
  145.         inc si
  146.         pop ax
  147.         call PutHexWord        ; Put driver offset
  148.         pop bx
  149.         add si,5
  150.  
  151.         test byte ptr es:[bx+5],80h
  152.         jz block_dev        ; Jump if block device
  153.  
  154.         mov cl,4        ; copy device name (blank-padded)
  155.         mov di,10
  156. next_w:
  157.         mov ax,es:[bx+di]
  158.         mov [si],ax
  159.         add si,2
  160.         add di,2
  161.         loop next_w
  162.         inc si
  163.  
  164.         mov ax,es
  165.         cmp ax,0070h
  166.         jbe addr_nextdrv
  167.  
  168.         push es
  169.         push si
  170.         dec ax
  171.         mov es,ax
  172.  
  173.         mov cl,8        ; copy driver's name
  174.         mov di,cx
  175. next_chard:
  176.         mov al,es:[bx+di]
  177.         cmp al,0
  178.         jz str_end1
  179.  
  180.         ; check chars : " * + , . \ ; : > < = ? [ ]
  181.         cmp al,32
  182.         jb unknown_drvname
  183.         cmp al,34
  184.         je unknown_drvname
  185.         cmp al,45
  186.         je ok_char1
  187.         cmp al,42
  188.         jb ok_char1
  189.         cmp al,47
  190.         jbe unknown_drvname
  191.         cmp al,58
  192.         jb ok_char1
  193.         cmp al,63
  194.         jbe unknown_drvname
  195.         cmp al,91
  196.         jb ok_char1
  197.         cmp al,93
  198.         jbe unknown_drvname
  199.         cmp al,127
  200.         ja unknown_drvname
  201. ok_char1:
  202.         mov [si],al
  203.         inc di
  204.         inc si
  205.         loop next_chard
  206. str_end1:
  207.         pop ax
  208.         pop es
  209.         jmp short addr_nextdrv
  210. unknown_drvname:
  211.         pop si
  212.         pop es
  213.         jmp short addr_nextdrv
  214.  
  215. block_dev:        ; Block devices show as A: - C:
  216.         mov word ptr [si],':'*256+'A'
  217.         mov word ptr [si+2],'-'*256+' '
  218.         mov word ptr [si+4],'C'*256+' '
  219.         mov byte ptr [si+6],':'
  220.         add si,7
  221. addr_nextdrv:                ; output string
  222.         mov cx,si
  223.         sub cx,offset buff_str
  224.         mov si,offset buff_str
  225.         mov ah,2
  226. next_ch:
  227.         mov dl,[si]
  228.         int 21h
  229.         inc si
  230.         loop next_ch
  231.  
  232.         mov dl,13
  233.         int 21h
  234.         mov dl,10
  235.         int 21h
  236.  
  237.         les bx,es:[bx]
  238.         cmp bx,-1        ; FFFF = last device in the chain
  239.         je exit_dispdrv
  240.         jmp next_drv
  241. exit_dispdrv:
  242.         ret
  243. Display_DRV    endp
  244.  
  245. Display_MCB    proc near
  246.         call put_head_table
  247.  
  248.         mov ah,52h
  249.         int 21h            ; Get DOS List Of Lists (ES:BX)
  250.  
  251.         mov es,es:[bx-2]    ; Get Root Memory Control Block
  252. next_block:
  253.         mov dx,es
  254.         mov bx,ds
  255.         mov es,bx
  256.         mov di,offset buff_str
  257.         mov cx,25
  258.         mov ax,2020h
  259.         rep stosw
  260.         mov es,dx        ; Fill string buffer with spaces
  261.  
  262.         call PutAddrSizeBlock    ; print address & size of block
  263.         call PutNameTypeBlock    ; print name & type of block
  264.  
  265.         mov dx,offset buff_str
  266.         mov ah,9
  267.         int 21h            ; Output string
  268.  
  269.         cmp byte ptr es:[0],'Z'    ; Last block ?
  270.         je exit_dispmcb        ; yes
  271.                     ; no
  272.         mov ax,es
  273.         add ax,es:[3]
  274.         inc ax
  275.         mov es,ax        ; ES -> points to the next MCB
  276.         jmp next_block
  277. exit_dispmcb:
  278.         ret
  279. Display_MCB    endp
  280.  
  281. ; Procedure to print the header string for memory block
  282. put_head_table    proc near
  283.         xor cx,cx
  284.         mov ax,ds
  285.         mov es,ax
  286.         mov di,offset buff_str
  287.         mov dx,di
  288.         inc di
  289.         mov si,offset addr_str
  290.         mov cl,7
  291.         rep movsb
  292.         add di,7
  293.         mov si,offset name_str
  294.         mov cl,4
  295.         rep movsb
  296.         add di,9
  297.         mov si,offset type_str
  298.         mov cl,4
  299.         rep movsb
  300.         add di,9
  301.         mov si,offset size_str
  302.         mov cl,4
  303.         rep movsb
  304.  
  305.         mov ah,9
  306.         int 21h
  307.  
  308.         mov di,offset buff_str
  309.         mov ax,2d2dh
  310.         mov cl,25
  311.         rep stosw        ; "--------------"
  312.  
  313.         mov ah,9
  314.         int 21h
  315.         ret
  316. put_head_table    endp
  317.  
  318. ; Put address and size of memory block
  319. PutAddrSizeBlock proc near
  320.         mov ax,es
  321.         mov dx,ax
  322.         shr ax,12
  323.         shl dx,4
  324.         mov bx,offset buff_str
  325.         mov si,1
  326.         call PutHexByte        ; Put high part of address
  327.         mov ax,dx
  328.         call PutHexWord        ; Put low part
  329.         mov si,45
  330.         mov ax,es:[3]        ; AX = block size (in paragraphs)
  331.         inc ax            ; +1
  332.         mov dx,ax
  333.         shr dx,12
  334.         shl ax,4        ; DX:AX = block size
  335.         call PutDecDWord    ; Put block size
  336.         ret
  337. PutAddrSizeBlock endp
  338.  
  339. ; Put name and type of memory block
  340. PutNameTypeBlock proc near
  341.         xor cx,cx
  342.         mov ax,es:[1]        ; AX = owner field
  343.         or ax,ax        ; 0 - free block
  344.         jnz no_free_block
  345.         jmp dos_block
  346. no_free_block:
  347.         cmp ax,8        ; 8 - block owned by DOS
  348.         jne no_dos_block
  349.         jmp dos_block
  350. no_dos_block:
  351.         push es
  352.         mov dx,es
  353.         mov es,ax
  354.         inc dx
  355.         cmp dx,es:[2ch]        ; Environment block ?
  356.         jne no_env_block    ; NO
  357.                     ; YES
  358.         mov di,offset buff_str+25    ; Put "Environment"
  359.         mov si,offset env
  360.         mov cl,11
  361.         jmp short host_name
  362. no_env_block:
  363.         mov ax,es
  364.         cmp ax,dx        ; Program block ?
  365.         jne no_progr        ; NO
  366.                     ; YES
  367.         mov di,offset buff_str+27    ; Put "Program"
  368.         mov si,offset prg
  369.         mov cl,7
  370.         jmp short host_name
  371. no_progr:
  372.         ; if block is neither env or prg,
  373.         ; it is data block (may be)
  374.  
  375.         mov di,offset buff_str+28    ; Put "Data"
  376.         mov si,offset dat
  377.         mov cl,4
  378. host_name:
  379.         call str_cpy        ; Put host's name
  380.         mov ax,es
  381.         dec ax
  382.         mov es,ax
  383.  
  384.         ; check filename symbols
  385.         ; check chars : " * + , . \ ; : > < = ? [ ] 
  386.         mov cl,8
  387.         mov di,cx
  388. chk_char:
  389.         mov al,es:[di]
  390.         or al,al
  391.         jz end_chk
  392.         cmp al,32
  393.         jbe unknown_name
  394.         cmp al,34
  395.         je unknown_name
  396.         cmp al,45
  397.         je ok_char
  398.         cmp al,42
  399.         jb ok_char
  400.         cmp al,47
  401.         jbe unknown_name
  402.         cmp al,58
  403.         jb ok_char
  404.         cmp al,63
  405.         jbe unknown_name
  406.         cmp al,91
  407.         jb ok_char
  408.         cmp al,93
  409.         jbe unknown_name
  410. ok_char:
  411.         inc di
  412.         loop chk_char
  413. end_chk:
  414.         cmp di,8
  415.         je unknown_name
  416.  
  417.         mov cl,8        ; Copy owner's name from
  418.         mov di,cx        ; MCB (ASCIIZ or 8 chars)
  419.         mov si,offset buff_str+14
  420. next_char:
  421.         mov al,es:[di]
  422.         cmp al,0
  423.         jz str_end
  424.         mov [si],al
  425.         inc di
  426.         inc si
  427.         loop next_char
  428. str_end:
  429.         pop es
  430.         ret
  431. unknown_name:            ; There's a spy in your system (joke)
  432.         pop es
  433.         mov di,offset buff_str+14    ; Put "Unknown"
  434.         mov si,offset unkn
  435.         mov cl,6
  436.         jmp short str_cpy
  437. dos_block:
  438.             ; Copy string "MSDOS"
  439.  
  440.         mov di,offset buff_str+14
  441.         mov si,offset msd
  442.         mov cl,5
  443. nextb:
  444.         mov dl,[si]
  445.         mov [di],dl
  446.         inc si
  447.         inc di
  448.         loop nextb
  449.  
  450.         or ax,ax
  451.         jz free_block            ; Jump if free block
  452.  
  453.         add di,6
  454.         cmp word ptr es:[8],'C'*256+'S'    ; System Code ?
  455.         jne no_syscode            ; NO
  456.                         ; YES
  457.         mov si,offset sys_str        ; Put "System"
  458.         mov cl,6
  459.         call str_cpy
  460.         inc di
  461.  
  462.         mov si,offset cod        ; Put "Code"
  463.         mov cl,4
  464.         jmp short str_cpy
  465. no_syscode:
  466.             ; If not SC then SD "System Data"
  467.  
  468.         mov si,offset sys_str    ; Put "System"
  469.         mov cl,6
  470.         call str_cpy
  471.         inc di
  472.  
  473.         mov si,offset dat    ; Put "Data"
  474.         mov cl,4
  475.         jmp short str_cpy
  476. free_block:
  477.         ; ooo! free block "free"
  478.  
  479.         mov si,offset fre    ; Put "free"
  480.         add di,9
  481.         mov cl,4
  482.  
  483.         ; str_cpy copeis blocks from DS:SI to DS:DI
  484.         ; CX - bytes count
  485. str_cpy:
  486.         lodsb
  487.         mov [di],al
  488.         inc di
  489.         loop str_cpy
  490.         ret
  491. PutNameTypeBlock endp
  492.  
  493. ; convert byte to hex
  494. ; AL = 8 bit value to convert
  495. ; ds:[bx+si] <- string
  496.  
  497. PutHexByte    proc near
  498.         push bx
  499.         add si,bx
  500.         lea bx,hex
  501.         mov ah,al
  502.         shr al,4
  503.         xlat        ; Convert high half byte
  504.         mov [si],al
  505.         mov al,ah
  506.         and al,0fh
  507.         xlat        ; Convert low half byte
  508.         mov [si+1],al
  509.         add si,2
  510.         pop bx
  511.         sub si,bx
  512.         ret
  513. PutHexByte    endp
  514.  
  515. ; Covert word to hex
  516. ; AX = 16 bit value to convert
  517. PutHexWord    proc near
  518.         push ax
  519.         mov al,ah
  520.         call PutHexByte
  521.         pop ax
  522.         call PutHexByte
  523.         ret
  524. PutHexWord    endp
  525.  
  526. ; Binary to ASCII conversion (right aligned)
  527. ; DX:AX = 32 bit value to convert
  528. PutDecDword    proc near
  529.         push bx
  530.         add si,bx
  531.         mov bx,10
  532. next_digitd:
  533.         div bx        ; Convert to decimal digits
  534.         add dl,'0'
  535.         mov [si],dl
  536.         dec si
  537.         xor dx,dx
  538.         or ax,ax
  539.         jnz next_digitd
  540.         pop bx
  541.         sub si,bx
  542.         ret
  543. PutDecDword    endp
  544. end Start
  545.